﻿using System;
using System.Text;
using Xunit;

namespace Unity.String.Tests.Text
{
    public class ValueStringBuilderTest
    {
        [Fact]
        public void ConstructorTest()
        {
            var testValueStringBuilder = new ValueStringBuilder();
            Assert.Equal(0, testValueStringBuilder.Capacity);
            Assert.Equal(0, testValueStringBuilder.Length);

            int bufferSize = 1024;
            char[] buffer = new char[bufferSize];
            Span<char> spanBuffer = buffer.AsSpan();
            var testValueStringBuilderWithBuffer = new ValueStringBuilder(spanBuffer);
            Assert.Equal(bufferSize, testValueStringBuilderWithBuffer.Capacity);
            Assert.Equal(0, testValueStringBuilder.Length);

            int testInitialCapacity = 1024;
            var testValueStringBuilderWithCapacity = new ValueStringBuilder(testInitialCapacity);
            Assert.Equal(testInitialCapacity, testValueStringBuilderWithCapacity.Capacity);
            Assert.Equal(0, testValueStringBuilder.Length);
        }

        [Fact]
        public void MethodsTest()
        {
        }

        //[Fact]
        public void AppendTest()
        {
            {
                var testValueStringBuilder = new ValueStringBuilder();
                string testResultAppendString = "";
                int appendSymbolsCounter = 0;
                
                int testEnsureCapacity = 128;
                testValueStringBuilder.EnsureCapacity(testEnsureCapacity);
                Assert.Equal(testEnsureCapacity, testValueStringBuilder.Capacity);
                Assert.Equal(testResultAppendString.Length, testValueStringBuilder.Length);
                Assert.Equal(testResultAppendString, testValueStringBuilder.ToString());

                // testValueStringBuilder.Append(null);
                // Assert.Equal(appendSymbolsCounter, testValueStringBuilder.Length);
                // Assert.Equal(testResultAppendString.Length, testValueStringBuilder.Length);
                // Assert.Equal(testResultAppendString, testValueStringBuilder.ToString());

                string testStringValue = "Lorem Ipsum";
                testValueStringBuilder.Append(testStringValue);
                testResultAppendString += testStringValue;
                appendSymbolsCounter += testStringValue.Length;
                Assert.Equal(appendSymbolsCounter, testValueStringBuilder.Length);
                Assert.Equal(testResultAppendString.Length, testValueStringBuilder.Length);
                Assert.Equal(testResultAppendString, testValueStringBuilder.ToString());

                
                string testOneCharStringValue = ",";
                testValueStringBuilder.Append(testOneCharStringValue);
                Assert.Equal(1, testValueStringBuilder.Length);
                testResultAppendString += testOneCharStringValue;
                appendSymbolsCounter += testOneCharStringValue.Length;
                
                Assert.Equal(appendSymbolsCounter, testValueStringBuilder.Length);
                Assert.Equal(testResultAppendString.Length, testValueStringBuilder.Length);
                Assert.Equal(testResultAppendString, testValueStringBuilder.ToString());
                
                char testSymbol = 'O';
                testValueStringBuilder.Append(testSymbol);
                testResultAppendString += testSymbol;
                appendSymbolsCounter += 1;
                Assert.Equal(appendSymbolsCounter, testValueStringBuilder.Length);
                Assert.Equal(testResultAppendString.Length, testValueStringBuilder.Length);
                Assert.Equal(testResultAppendString, testValueStringBuilder.ToString());

                int testSymbolCount = 5;
                testValueStringBuilder.Append(testSymbol, testSymbolCount);
                testResultAppendString += new string(testSymbol, testSymbolCount);
                appendSymbolsCounter += testSymbolCount;
                Assert.Equal(appendSymbolsCounter, testValueStringBuilder.Length);
                Assert.Equal(testResultAppendString.Length, testValueStringBuilder.Length);
                Assert.Equal(testResultAppendString, testValueStringBuilder.ToString());

                ReadOnlySpan<char> testReadOnlySpanValue = "   ".AsSpan();
                testValueStringBuilder.Append(testReadOnlySpanValue);
                appendSymbolsCounter += testReadOnlySpanValue.Length;
                Assert.Equal(appendSymbolsCounter, testValueStringBuilder.Length);
                
                string testCharArrayString = "Dolor sit amet";
                appendSymbolsCounter += testCharArrayString.Length;
                unsafe
                {
                    fixed (char* testCharArrayPointer = testCharArrayString)
                    {
                        testValueStringBuilder.Append(testCharArrayPointer, testCharArrayString.Length);
                    }
                }
                Assert.Equal(appendSymbolsCounter, testValueStringBuilder.Length);

                int testSpanLength = 10;
                Span<char> returnSpan = testValueStringBuilder.AppendSpan(testSpanLength);
                appendSymbolsCounter += testSpanLength;
                Assert.Equal(appendSymbolsCounter, testValueStringBuilder.Length);

                // string testResultAppendString = testStringValue + testOneCharStringValue 
                //     + testSymbol + new string(testSymbol, testSymbolCount)
                //     + testReadOnlySpanValue.ToString()
                //     + testCharArrayString
                //     + returnSpan.ToString();
                // Assert.Equal(testResultAppendString.Length, testStringValue.ToString().Length);
            }

            {
                var testValueStringBuilder = new ValueStringBuilder();
                string testStringValue = "Lorem Ipsum";
                testValueStringBuilder.Append(testStringValue);
                Assert.Equal(testStringValue.Length, testValueStringBuilder.Length);
            }
            
            {
                var testValueStringBuilder = new ValueStringBuilder();
                char testSymbol = 'O';
                testValueStringBuilder.Append(testSymbol);
                Assert.Equal(1, testValueStringBuilder.Length);
            }
            
            {
                var testValueStringBuilder = new ValueStringBuilder();
                char testSymbol = 'O';
                int testSymbolCount = 5;
                testValueStringBuilder.Append(testSymbol, testSymbolCount);
                Assert.Equal(testSymbolCount, testValueStringBuilder.Length);
            }
            
            {
                var testValueStringBuilder = new ValueStringBuilder();
                ReadOnlySpan<char> testReadOnlySpanValue = "   ".AsSpan();
                testValueStringBuilder.Append(testReadOnlySpanValue);
                Assert.Equal(testReadOnlySpanValue.Length, testValueStringBuilder.Length);
            }
            
            {
                var testValueStringBuilder = new ValueStringBuilder();
                int testSpanLength = 10;
                testValueStringBuilder.AppendSpan(testSpanLength);
                Assert.Equal(testSpanLength, testValueStringBuilder.Length);
            }
            
            {
                var testValueStringBuilder = new ValueStringBuilder();
                string testCharArrayString = "Dolor sit amet";
                unsafe
                {
                    fixed (char* testCharArrayPointer = testCharArrayString)
                    {
                        testValueStringBuilder.Append(testCharArrayPointer, testCharArrayString.Length);
                    }
                }
                Assert.Equal(testCharArrayString.Length, testValueStringBuilder.Length);
            }
        }
    }
}